package org.zk.dubbo_consumer.controller;


import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.zk.dubbo_consumer.util.AlipayConfig;
import org.zk.dubbo_consumer.util.OrderUtil;
import org.zk.entity.*;
import org.zk.service.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.*;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author Alicelonely
 * @since 2019-12-11
 */
@Controller
@RequestMapping("/order")
public class OrderController {


    @Resource
    OrderService orderService;
    @Resource
    CourseService courseService;
    @Resource
    BroadcastService broadcastService;
    @Resource
    StudyService studyService;
    @Resource
    TeacherService teacherService;

    @ResponseBody
    @RequestMapping("/toOrder")
    public ModelAndView getOrder(int userId){
        List<Order> Orderlist=orderService.getOrder(userId);
        ModelAndView mv=new ModelAndView("person/order");
        mv.addObject("Orderlist",Orderlist);
//        return new ModelAndView("person/order");
        return mv;
    }

//    @ResponseBody
//    @RequestMapping("/del")
//    public String delOrder(int orderId ){
//        orderService.delOrder(orderId);
//        return "person/order";
//    }


    /**
     * 高申 2019-12-16
     * 课程播放时异步判断，
     * 根据用户id，课程id，以及账单的状态state=1，判断用户是否已购买该课程
     */
    @RequestMapping("/check")
    @ResponseBody
    public Map check(HttpSession session, Integer courseId){
        int result=0;
        User user = (User) session.getAttribute("user");
        Map<String,Integer> maps=new HashMap<>();
        maps.put("userId",user.getUserId());
        maps.put("courseId",courseId);
        maps.put("orderState",1);
        //判断返回值
        int num=orderService.queryUserOrder(maps);
        if(num!=0){//已购买该课程
            result=1;
        }
        maps.put("result",result);
        return maps;
    }


    /**
     * 高申 2019-12-16
     * 课程播放时异步判断，
     * 根据用户id，课程id，以及账单的状态state=1，判断用户是否已购买该课程
     */
    @RequestMapping("/broadcastCheck")
    @ResponseBody
    public Map broadcastCheck(HttpSession session, Integer broadcastId) {
        int result = 0;
        User user = (User) session.getAttribute("user");
        Map<String, Integer> maps = new HashMap<>();
        maps.put("userId", user.getUserId());
        maps.put("broadcastId", broadcastId);
        maps.put("orderState", 1);
        //判断返回值
        int num = orderService.queryUserBroadcastOrder(maps);
        if (num != 0) {//已购买该课程
            result = 1;
        }
        maps.put("result", result);
        return maps;
    }

    /**
     * 高申 2019-12-17
     *创建支付订单
     * 创建一个新订单（在数据库中设置为支付订单的失效事件，失效时间为30min，失效后改为状态-1）
     */
    @GetMapping("/createOrder")
    public String createOrder(Integer courseId, Double coursePrice,ModelMap modelMap,HttpSession session){
        //创建一个新订单（在数据库中设置为支付订单的失效事件，失效时间为30min，失效后改为状态-1）
        Order orders=new Order();
        //订单id
        String orderId= OrderUtil.genUniqueKey();//根据工具类生成订单id
        orders.setOrderId(orderId);//订单id
        //下单人id，从session中获取当前用户
        User user= (User) session.getAttribute("user");
        orders.setUser(user);
        //下单商品id（课程id）
        Course c=new Course();
        c.setCourseId(courseId);
        orders.setCourse(c);
        //下单金额，在这里判断是普通用户还是会员
        Integer userVip = user.getUserVip();
        System.out.println("uservip============"+userVip);
        if(userVip==1){
            orders.setOrderTotal(coursePrice*0.8);//会员8折
        }else{
            orders.setOrderTotal(coursePrice);//普通用户
        }
        //订单状态(0未支付，1已支付，-1已失效)
        orders.setOrderState(0);
        orderService.insertcreateOrder(orders);
        Course course=courseService.queryOneCourse(courseId);
        modelMap.put("order",orders);
        modelMap.put("course",course);
        return "user/order-pay";
    }


    /**
     * 高申 2019-12-17
     * 创建支付订单
     * 创建一个新订单（在数据库中设置为支付订单的失效事件，失效时间为30min，失效后改为状态-1）
     */
    @GetMapping("/createBroadcastOrder")
    public String createBroadcastOrder(Integer broadcastId, Double broadcastPrice, ModelMap modelMap, HttpSession session) {
        //创建一个新订单（在数据库中设置为支付订单的失效事件，失效时间为30min，失效后改为状态-1）
        Order orders = new Order();
        //订单id
        String orderId = OrderUtil.genUniqueKey();//根据工具类生成订单id
        orders.setOrderId(orderId);//订单id
        //下单人id，从session中获取当前用户
        User user = (User) session.getAttribute("user");
        orders.setUser(user);
        //下单商品id（课程id）
        Broadcast b = new Broadcast();
        b.setBroadcastId(broadcastId);
        orders.setBroadcast(b);
        //下单金额，在这里判断是普通用户还是会员
        Integer userVip = user.getUserVip();
        System.out.println("uservip============" + userVip);
        if (userVip == 1) {
            orders.setOrderTotal(broadcastPrice * 0.8);//会员8折
        } else {
            orders.setOrderTotal(broadcastPrice);//普通用户
        }
        //订单状态(0未支付，1已支付，-1已失效)
        orders.setOrderState(0);
        orderService.insertcreateOrder(orders);
        Broadcast broadcast = broadcastService.getBroadcastById(broadcastId);
        modelMap.put("order", orders);
        modelMap.put("broadcast", broadcast);
        return "user/order-pay";
    }

    /**
     * 高申 2019-12-17
     * 调用支付宝接口，支付订单
     */
    @RequestMapping(value = "/goPay" ,produces = "text/html; charset=UTF-8")
    @ResponseBody
    public String goPay(String orderId) throws Exception {
        Order order=orderService.queryOneOrder(orderId);//courseId,orderTotal,
        //根据订单中的courseId在商品表中查询到商品的具体信息
        Course course=courseService.queryOneCourse(order.getCourse().getCourseId());//courseName
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);
        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(AlipayConfig.return_url);
        //alipayRequest.setNotifyUrl(AlipayConfig.notify_url);

        //商户订单号，商户网站订单系统中唯一订单号，必填
        String out_trade_no = orderId;
        //付款金额，必填
        Double total_amount = order.getOrderTotal();
        //订单名称（课程名），必填
        String subject = course.getCourseName();
        /*//商品描述，可空
        String body = "用户订购商品个数：" + orders.getBuyCounts();*/

        // 该笔订单允许的最晚付款时间，逾期将关闭交易。
        // 取值范围：1m～15d。m-分钟，h-小时，d-天，1c-当天（1c-当天的情况下，无论交易何时创建，都在0点关闭）。 该参数数值不接受小数点， 如 1.5h，可转换为 90m。
        String timeout_express = "30m";

        alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\","
                + "\"total_amount\":\"" + total_amount + "\","
                + "\"subject\":\"" + subject + "\","
                + "\"timeout_express\":\"" + timeout_express + "\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
        //请求
        String result = alipayClient.pageExecute(alipayRequest).getBody();
        return result;
    }


    /**
     * 高申 2019-12-17
     * 调用支付宝接口，支付订单
     */
    @RequestMapping(value = "/goBroadcastPay", produces = "text/html; charset=UTF-8")
    @ResponseBody
    public String goBroadcastPay(String orderId) throws Exception {
        Order order = orderService.queryOneBroadcastOrder(orderId);//courseId,orderTotal,
        //根据订单中的broadcastId在商品表中查询到商品的具体信息
        Broadcast broadcast = broadcastService.getBroadcastById(order.getBroadcast().getBroadcastId());//broadcastName
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);
        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(AlipayConfig.return_broadcast_url);
        //alipayRequest.setNotifyUrl(AlipayConfig.notify_url);

        //商户订单号，商户网站订单系统中唯一订单号，必填
        String out_trade_no = orderId;
        //付款金额，必填
        Double total_amount = order.getOrderTotal();
        //订单名称（课程名），必填
        String subject = broadcast.getBroadcastTitle();
        /*//商品描述，可空
        String body = "用户订购商品个数：" + orders.getBuyCounts();*/

        // 该笔订单允许的最晚付款时间，逾期将关闭交易。
        // 取值范围：1m～15d。m-分钟，h-小时，d-天，1c-当天（1c-当天的情况下，无论交易何时创建，都在0点关闭）。 该参数数值不接受小数点， 如 1.5h，可转换为 90m。
        String timeout_express = "30m";

        alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
                + "\"total_amount\":\""+ total_amount +"\","
                + "\"subject\":\""+ subject +"\","
                + "\"timeout_express\":\""+ timeout_express +"\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
        //请求
        String result = alipayClient.pageExecute(alipayRequest).getBody();
        return result;
    }


    /**
     * 支付成功同步通知
     */
    @RequestMapping(value = "/alipayBroadcastReturnNotice")
    public ModelAndView alipayBroadcastReturnNotice(HttpServletRequest request,HttpSession session
    ) throws Exception {

        System.out.println("支付成功, 进入同步通知接口...");
        //获取支付宝GET过来反馈信息
        Map<String, String> params = new HashMap();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用
            valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }

        //定义courseId变量，在if中赋值，存入map，传递到支付成功页面接收
        int broadcastId = 0;

        //调用SDK验证签名
        boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type);

        if (signVerified) {
            //商户订单号
            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");

            //支付宝交易号
            String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");

            //付款金额
            String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8");

            System.out.println(out_trade_no);
            Order order = orderService.queryOneBroadcastOrder(out_trade_no);//courseId,orderTotal,
            //根据订单中的courseId在商品表中查询到商品的具体信息
            broadcastId = order.getBroadcast().getBroadcastId();
            Broadcast broadcast = broadcastService.getBroadcastById(broadcastId);//courseName
            User user = (User) session.getAttribute("user");
            //=================================================================
            //1.修改订单状态，改为支付成功，已付款;
            Order orders = new Order();
            orders.setOrderId(out_trade_no);
            orders.setOrderState(1);
            orders.setOrderPayTime(new Date());
            orderService.updateOrder(orders);

            //2.该课程的销量加1（courseCount）
            Integer userVip = user.getUserVip();
            if (userVip == 1) {//vip购买
                broadcast.setBroadcastUser(0);
                broadcast.setBroadcastVip(1);
            } else {//普通用户购买
                broadcast.setBroadcastUser(1);
                broadcast.setBroadcastVip(0);
            }
            broadcastService.updateBroadcastCount(broadcast);

            //3.用户学习表中增加一条记录
            Study study = new Study();
            study.setBroadcast(broadcast);
            study.setUser(user);
            studyService.createStudy(study);

            //4.更新教师收入金额(teacher_money)
            Teacher teacher = new Teacher();
            Integer teacherId = broadcast.getTeacher().getTeacherId();
            teacher.setTeacherId(teacherId);
            teacher.setTeacherMoney(Double.parseDouble(total_amount));
            teacherService.insertTeacherMoneyByCourse(teacher);



            System.out.println("*********************支付成功(支付宝同步通知)*********************");
            System.out.println("* 订单号: "+ out_trade_no);
            System.out.println("* 支付宝交易号: "+ trade_no);
            System.out.println("* 实付金额: "+total_amount);
            System.out.println("* 购买课程: "+broadcast.getBroadcastTitle());
            System.out.println("***************************************************************");


        }else {
            System.out.println("支付, 验签失败...");
        }

        //支付成功向paySuccess.html页面传入courseID，以便于返回该课程页
        Map<String,Integer> maps=new HashMap();
        maps.put("broadcastId",broadcastId);
        return new ModelAndView("/user/payBroadcastSuccess",maps);
    }


    /**
     * 支付成功同步通知
     */
    @RequestMapping(value = "/alipayReturnNotice")
    public ModelAndView alipayReturnNotice(HttpServletRequest request,HttpSession session) throws Exception {
        System.out.println("支付成功, 进入同步通知接口...");
        //获取支付宝GET过来反馈信息
        Map<String,String> params = new HashMap();
        Map<String,String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用
            valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }

        //定义courseId变量，在if中赋值，存入map，传递到支付成功页面接收
        int courseId=0;

        //调用SDK验证签名
        boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type);

        if(signVerified) {
            //商户订单号
            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");

            //支付宝交易号
            String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");

            //付款金额
            String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"),"UTF-8");


            Order order=orderService.queryOneOrder(out_trade_no);//courseId,orderTotal,
            //根据订单中的courseId在商品表中查询到商品的具体信息
            courseId=order.getCourse().getCourseId();
            Course course=courseService.queryOneCourse(courseId);//courseName
            User user = (User) session.getAttribute("user");
            //=================================================================
            //1.修改订单状态，改为支付成功，已付款;
            Order orders=new Order();
            orders.setOrderId(out_trade_no);
            orders.setOrderState(1);
            orders.setOrderPayTime(new Date());
            orderService.updateOrder(orders);

            //2.该课程的销量加1（courseCount）
            Integer userVip = user.getUserVip();
            if(userVip==1){//vip购买
                course.setCountUser(0);
                course.setCountVip(1);
            }else{//普通用户购买
                course.setCountUser(1);
                course.setCountVip(0);

            }
            courseService.updateCourseCount(course);

            //3.用户学习表中增加一条记录
            Study study=new Study();
            study.setCourse(course);
            study.setUser(user);
            studyService.createStudy(study);

            //4.更新教师收入金额(teacher_money)
            Teacher teacher=new Teacher();
            Integer teacherId = course.getTeacher().getTeacherId();
            teacher.setTeacherId(teacherId);
            teacher.setTeacherMoney(Double.parseDouble(total_amount));
            teacherService.insertTeacherMoneyByCourse(teacher);



            System.out.println("*********************支付成功(支付宝同步通知)*********************");
            System.out.println("* 订单号: "+ out_trade_no);
            System.out.println("* 支付宝交易号: "+ trade_no);
            System.out.println("* 实付金额: "+total_amount);
            System.out.println("* 购买课程: "+course.getCourseName());
            System.out.println("***************************************************************");


        }else {
            System.out.println("支付, 验签失败...");
        }

        //支付成功向paySuccess.html页面传入courseID，以便于返回该课程页
        Map<String,Integer> maps=new HashMap();
        maps.put("courseId",courseId);

        return new ModelAndView("/user/paySuccess",maps);
    }

    @RequestMapping("/success")
    public String toSuccess(){
        return "/user/paySuccess";
    }


    public OrderService getOrderService() {
        return orderService;
    }

    public void setOrderService(OrderService orderService) {
        this.orderService = orderService;
    }

    public CourseService getCourseService() {
        return courseService;
    }

    public void setCourseService(CourseService courseService) {
        this.courseService = courseService;
    }

    public StudyService getStudyService() {
        return studyService;
    }

    public void setStudyService(StudyService studyService) {
        this.studyService = studyService;
    }
}



